import storage from '../cache/gh-storage.js';
import file from '../cache/gh-file.js';
import config from '../config/index.js';
import { GHHttp} from '../net/http/fetch.js';
import context from '../utils/gh-context/gh-context.js';
import Mutex from '../utils/gh-locks/gh-locks-mutex.js';
import { anaEventMap, anaPageMap } from './analyze-event.js';
import regeneratorRuntime from '../vendor/regenerator-runtime/runtime.js';

class GHAnalyze {
  constructor() {
    // 统计队列
    this.queue = new Array();
    // 统计预备队列
    this.reserves = new Array();
    // 是否正在同步标识
    this.sync = false;
    // 同步频率（ms）
    this.interval = config.analyze.interval || 15000;
    // 互斥锁
    this.mutex = new Mutex();
    // 分析文件存取路径
    this.anaFilePath = `${config.analyze.filePath}${config.analyze.fileName}`;
  }
  /**
   * 初始化统计
  */
  async init() {
    let res = await file.access(this.anaFilePath);
    if (res) {
      res = await file.mkdir(config.analyze.filePath);
    }
    //从analyze文件初始化queue
    try {
      res = await file.readString(this.anaFilePath);
    } catch(e) {
      console.error(e);
    }
    this.queue = JSON.parse(res) || [];
    if (this.queue.length > 0) {
      this.sync = true;
      this._syncTimedTask();
    }
    // 定时任务
    this.timedTask = setInterval(this._syncTimedTask, this.interval);
  }
  /**
  停止统计,但只是停上同步记录到服务器
  */
  stop() {
    clearInterval(this.timedTask);
  }
  /**
  记录一次事件的点击，id请提前在后台定义好,未创建的id记录将无效
  @param name 自定义事件name，提前在网站端创建
  @param ext 可JSON序列化的扩展数据
  */
  event(name, ext) {
    let record = this._analyzeRecord('event', name, target);
    if (!record) {
      return;
    }
    this._appendRecord(record);
  }
  /**
  记录某个页面访问的开始
  建议在Page的onShow生命周期函数中调用
  @param name 页面名称,ext 可JSON序列化的扩展数据
  */
  pageStart(name, ext) {
    let record = this._analyzeRecord('page_start', name, target);
    if (!record) {
      return;
    }
    this._appendRecord(record);
  }
  /**
   记录某个页面访问的结束
   建议在Page的onHide生命函数中调用
   @param name 页面名称,ext 可JSON序列化的扩展数据
   */
  pageEnd(name, ext) {
    let record = this._analyzeRecord('page_end', name, target);
    if (!record) {
      return;
    }
    this._appendRecord(record);
  }
  // 生成单条统计记录
  _analyzeRecord(type, name, ext) {
    if (!name || name.length == 0) {
      console.warn('+++++++++:{name} param lost!');
      return;
    }

    let map = (type === 'event') ? anaEventMap : anaPageMap;
    let target = map.get(name) || {};

    const user = storage.getUserInfo();
    const user_id = (user && user.user_id) ? user.user_id : '';
    const local_id = context.uuuid();

    let record = {
      local_id,
      type,
      name,
      user_id,
      create_at: Date.now()
    }

    Object.assign(record, target || {}, ext || {});
    return record;
  }
  // 追加到队列及analyze文件
  _appendRecord(record) {
    if (!record) {
      return;
    }
    // 判断是在统计队列还是预备队列
    if (!this.sync) {
      this.queue.unshift(record);
    } else {
      this.reserves.unshift(record);
    }

    // 存analyze文件,异步加锁
    this.mutex.lock(() => {
      file.writeString(this.anaFilePath)
      .then(() => {
      })
      .catch(() => {
        console.error('+++++++++:write record to analyse file fail!')
      })
      .finally(() => {
        this.mutex.unlock();
      });    
    });
  }
  // 删除analyze文件中已经同步过的记录,可能比较耗时
  _delFromAnalyzeFile() {
    file.readString(this.anaFilePath)
    .then(() => {
    })
    .catch(() => {
    });
  }
  // 向服务器同步统计数据
  _syncTimedTask() {
    if (this.sync || this.queue.length == 0) {
      return;
    }
    // 设置同步状态
    this.sync = true;

    // 开始同步
    GHHttp({key: 'analyze', data: { jsonStr: JSON.stringify(this.queue) }})
      .then((res) => {
        if (res.code == '0') {
          this.sync = false;
          this.queue = [];
          this.queue = [...this.queue, ...this.reserves];
        }
      })
      .catch((e) => {
        this.sync = false;
        this.queue = [...this.queue, ...this.reserves];
        this.reserves = [];
      });
  }
}